package com.sotb.sender;

import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

/**
 * @author zsr 
 * 该类用于获取地理位置信息<br>
 * <p>startListening()	开始监听<br>
 * stopListening()	停止监听
 */
public class LocationInfo {
	
	private LocationManager locationManager = null;
	private Context context = null;
	private SMSSenderService smsSenderService;
	private MyLocationListener myLocationListener;
	private double[] latlang = {0,0};	//存储经纬度
	private Handler handler;
	private boolean originalGPSState = false;
	Message msg;
	
	/**
	 * 构造函数
	 * @param context 用于获取系统服务，从而得到位置监听功能
	 */
	LocationInfo(Context context){
		this.context = context;
		smsSenderService = (SMSSenderService)this.context;
		handler = smsSenderService.smsHandler;
		
		myLocationListener = new MyLocationListener();
		locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
		//String providerStr = getBetterProvider();
		String providerStr = "gps";
		locationManager.requestLocationUpdates(providerStr, 0, 0, myLocationListener);
		System.out.println("Location info provided by " + providerStr);
	}
	
	/**
	 * 获取地理位置(费时操作，阻塞线程)；可调用stop()主动结束监听
	 * @param time 自定义监听时间
	 */
	public void startListening(long timeToListen){
		System.out.println("startListening");
		if (!locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)){
			enableGPS();
			System.out.println("enabling gps");
		}
		else {
			originalGPSState = true;
			System.out.println("gps is already enabled");
		}
		//当超过预设的时间时停止监听
		try {
			Thread.sleep(timeToListen);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		stopListening();
	}
	
	/**停止监听*/
	public void stopListening(){
		locationManager.removeUpdates(myLocationListener);
		if(!originalGPSState)disableGPS();
	}
	
	/**开启GPS*/
	private void enableGPS(){
		if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
			changeGPSState();
	        System.out.println("GPS has been opened");
		}
	}
	
	/**关闭GPS*/
	private void disableGPS(){
		if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
			changeGPSState();
	        System.out.println("GPS has been closed");
		}
	}
	
	/**改变gps的开关状态*/
	private void changeGPSState(){
		Intent gpsIntent = new Intent();
        gpsIntent.setClassName("com.android.settings",
                        "com.android.settings.widget.SettingsAppWidgetProvider");
        gpsIntent.addCategory("android.intent.category.ALTERNATIVE");
        gpsIntent.setData(Uri.parse("custom:3"));
        try {
                PendingIntent.getBroadcast(context, 0, gpsIntent, 0).send();
        }
        catch (CanceledException e) {
                e.printStackTrace();
        }
	}
	
	/**
	 *  获取较好的Location provider
	 * @return String 代表provider类型，如"gps"
	 */
//	private String getBetterProvider(){
//		Criteria criteria = new Criteria();
//		//criteria.setAccuracy(Criteria.ACCURACY_FINE);
//		criteria.setAltitudeRequired(false);
//		criteria.setCostAllowed(true);
//		criteria.setSpeedRequired(false);
//		return locationManager.getBestProvider(criteria, false);
//	}
	
	/**location监听器*/
	private class MyLocationListener implements LocationListener{
		private Location currentBestLocation = null;
		private long lastSendTime = System.currentTimeMillis();
		private boolean isFirstTime = true;
		public void onLocationChanged(Location location) {
			if(isBetterLocation(location, currentBestLocation)){
				currentBestLocation = location;
			}
			
			//第一次等待30s以上发送
			if(isFirstTime && System.currentTimeMillis() - lastSendTime > Constant.HALF_MINUTE){
				isFirstTime = false;
				sendLocation();
			}
			
			//非第一次2min发送一次
			//test:暂时改为30s一次
			if(System.currentTimeMillis() - lastSendTime > Constant.HALF_MINUTE){
				sendLocation();
				lastSendTime = System.currentTimeMillis();
			}
			
			System.out.println("new location");
		}
		
		private void sendLocation(){
			latlang[0] = currentBestLocation.getLongitude();
				latlang[1] = currentBestLocation.getLatitude();
				msg = handler.obtainMessage();
				msg.obj = latlang;
				msg.sendToTarget();
				System.out.println("msg sent");
		}
		public void onProviderDisabled(String provider) {
			System.out.println("provider " + provider + " was disabled");
		}

		public void onProviderEnabled(String provider) {
			System.out.println("provider " + provider + " was enabled");
		}

		// Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
		public void onStatusChanged(String provider, int status, Bundle extras) {
			System.out.println("provider " + provider + " status was changed");
		}
		
		/** 
		 * 判断新获取的location是否比旧的location好
		 * @param location	新获取的location
		 * @param currentBestLocation	当前location
		 */
		protected boolean isBetterLocation(Location location, Location currentBestLocation){
			if (currentBestLocation == null) {
				return true;
		    }
		
		    //比较location的新旧
		    long timeDelta = location.getTime() - currentBestLocation.getTime();
		    boolean isSignificantlyNewer = timeDelta > Constant.TWO_MINUTES;
		    boolean isSignificantlyOlder = timeDelta < -Constant.TWO_MINUTES;
		    boolean isNewer = timeDelta > 0;
		
		    //location时间间隔超过两分钟则强制更新
		    if (isSignificantlyNewer) {
		        return true;
		    } else if (isSignificantlyOlder) {
		        return false;
		    }
		
		    //比较精确度
		    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
		    boolean isLessAccurate = accuracyDelta > 0;
		    boolean isMoreAccurate = accuracyDelta < 0;
		    boolean isSignificantlyLessAccurate = accuracyDelta > 200;
		
		    boolean isFromSameProvider = isSameProvider(location.getProvider(),
		            currentBestLocation.getProvider());
		
		    //结合时间和精度比较
		    if (isMoreAccurate) {
		        return true;
		    } else if (isNewer && !isLessAccurate) {
		        return true;
		    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
		        return true;
		    }
		    return false;
		}
		
		/**检测两个provider是否相同*/
		private boolean isSameProvider(String provider1, String provider2) {
		    if (provider1 == null) {
		      return provider2 == null;
		    }
		    return provider1.equals(provider2);
		}
    }
}
